const tools = {
  /**
   * 让滚动条滚到指定位置
   * @method scrollTop
   * @param {参数类型} el:滚动的元素,from:起始位置,to:结束位置,duration:滚动时间,endCallback:滚动结束的回调
   */
  scrollTop (el, from = 0, to, duration = 500, endCallback) {
    if (!window.requestAnimationFrame) {
      window.requestAnimationFrame =
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function (callback) {
          return window.setTimeout(callback, 1000 / 60)
        }
    }
    const difference = Math.abs(from - to)
    const step = Math.ceil((difference / duration) * 50)

    function scroll (start, end, step) {
      if (start === end) {
        endCallback && endCallback()
        return
      }

      let d = start + step > end ? end : start + step
      if (start > end) {
        d = start - step < end ? end : start - step
      }

      if (el === window) {
        window.scrollTo(d, d)
      } else {
        el.scrollTop = d
      }
      window.requestAnimationFrame(() => scroll(d, end, step))
    }
    scroll(from, to, step)
  },

  /**
   * 深克隆
   * @method deepCopy
   * @param {obj:any} 深克隆的数据
   * @return {any} 返回深克隆后的数据
   */
  deepClone (obj) {
    var type = Object.prototype.toString.call(obj) //通过原型对象获取对象类型
    var newObj
    if (type === '[object Array]') {
      //数组
      newObj = []
      if (obj.length > 0) {
        for (var x = 0; x < obj.length; x++) {
          newObj.push(deepClone(obj[x]))
        }
      }
    } else if (type === '[object Object]') {
      //对象
      newObj = {}
      for (var x in obj) {
        newObj[x] = deepClone(obj[x])
      }
    } else {
      //基本类型和方法可以直接赋值
      newObj = obj
    }
    return newObj
  },
  /**
   * 字符串转base64
   * @method b64EncodeUnicode
   * @param {string} str 需要转base64的字符串
   * @return {string} base64字符串
   */
  b64EncodeUnicode (str) {
    return btoa(
      encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
        return String.fromCharCode('0x' + p1)
      })
    )
  },
  /**
   * base64转字符串
   * @method b64DecodeUnicode
   * @param {string} str base64字符串
   * @return {string} base64转回的字符串
   */
  b64DecodeUnicode (str) {
    return decodeURIComponent(
      atob(str)
        .split('')
        .map(function (c) {
          return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
        })
        .join('')
    )
  },
  /**
   * px转rem
   * @param uiWidth 设计稿宽度
   */
  setRem (uiWidth = 750) {
    const baseSize = 16
    const scale = document.documentElement.clientWidth / uiWidth
    document.documentElement.style.fontSize = baseSize * scale + 'px'
  },
  /**
   * 加法运算，避免数据相加小数点后产生多位数和计算精度损失。
   *
   * @param num1加数1 | num2加数2
   */
  numAdd (num1, num2) {
    var baseNum, baseNum1, baseNum2
    try {
      baseNum1 = num1.toString().split('.')[1].length
    } catch (e) {
      baseNum1 = 0
    }
    try {
      baseNum2 = num2.toString().split('.')[1].length
    } catch (e) {
      baseNum2 = 0
    }
    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2))
    return (num1 * baseNum + num2 * baseNum) / baseNum
  },

  /**
   * 减法运算，避免数据相减小数点后产生多位数和计算精度损失。
   *
   * @param num1被减数  |  num2减数
   */
  numSub (num1, num2) {
    var baseNum, baseNum1, baseNum2
    var precision // 精度
    try {
      baseNum1 = num1.toString().split('.')[1].length
    } catch (e) {
      baseNum1 = 0
    }
    try {
      baseNum2 = num2.toString().split('.')[1].length
    } catch (e) {
      baseNum2 = 0
    }
    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2))
    precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2
    return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision)
  },

  /**
   * 乘法运算，避免数据相乘小数点后产生多位数和计算精度损失。
   *
   * @param num1被乘数 | num2乘数
   */
  numMulti (num1, num2) {
    var baseNum = 0
    try {
      baseNum += num1.toString().split('.')[1].length
    } catch (e) { }
    try {
      baseNum += num2.toString().split('.')[1].length
    } catch (e) { }
    return (
      (Number(num1.toString().replace('.', '')) * Number(num2.toString().replace('.', ''))) /
      Math.pow(10, baseNum)
    )
  },

  /**
   * 除法运算，避免数据相除小数点后产生多位数和计算精度损失。
   *
   * @param num1被除数 | num2除数
   */
  numDiv (num1, num2) {
    var baseNum1 = 0,
      baseNum2 = 0
    var baseNum3, baseNum4
    try {
      baseNum1 = num1.toString().split('.')[1].length
    } catch (e) {
      baseNum1 = 0
    }
    try {
      baseNum2 = num2.toString().split('.')[1].length
    } catch (e) {
      baseNum2 = 0
    }
    baseNum3 = Number(num1.toString().replace('.', ''))
    baseNum4 = Number(num2.toString().replace('.', ''))
    return (baseNum3 / baseNum4) * Math.pow(10, baseNum2 - baseNum1)
  },
  /**
   * 生成一个从 start 到 end 的连续数组
   * @param start
   * @param end
   */
  generateArray (start, end) {
    return Array.from(new Array(end + 1).keys()).slice(start)
  },
  /**
   * 防抖函数
   * @param fn
   * @param delay
   */
  debounce (fn, delay = 300) {
    let timer = null //借助闭包
    return function () {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(fn, delay) // 简化写法
    }
  },
  /**
   * 节流函数
   * @param fn
   * @param delay
   */
  throttle (fn, delay = 300) {
    let valid = true
    return function () {
      if (!valid) {
        return false
      }
      valid = false
      setTimeout(() => {
        fn()
        valid = true
      }, delay)
    }
  },
  /**
   * vue函数防抖
   * 触发事件后在n秒后执行，如果n秒内又触发事件，则重新计算时间
   */
  debounceVue (fn, wait = 300) {
    let timer
    return function () {
      let context = this
      let args = arguments
      if (timer) clearTimeout(timer)
      timer = setTimeout(() => {
        fn.apply(context, args)
      }, wait)
    }
  },

  /**
   * vue函数节流
   * 触发事件立即执行，但在n秒内连续触发则不执行
   */
  throttleVue (fn, wait = 300) {
    let timer
    return function () {
      if (timer != null) return
      let context = this
      let args = arguments
      fn.apply(context, args)
      timer = setTimeout(() => {
        timer = null
      }, wait)
    }
  },
  /**
   * 获取地址上的指定参数的值
   * @param name  String 需要获取的参数key
   */
  getQueryString (name = '') {
    return (
      decodeURIComponent(
        (new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(
          window.location.href
        ) || [, ''])[1].replace(/\+/g, '%20')
      ) || ''
    )
  },
  /**
   * uniapp获取地址上的指定参数的值
   * @param name  String 需要获取的参数key
   */
  getParams (name = '') {
    let param = this.getQueryString(name)
    return param
  },
  /**
   * 格式化时间戳
   * @param now  需要格式化的时间戳
   * return  返回一个对象，里面包含指定时间戳格式化的年月日时分秒
   */
  formatDate (now) {
    function Appendzero (obj) {
      if (obj < 10) return '0' + obj
      else return obj
    }
    var t = new Date(now)
    var year = t.getFullYear()
    var month = t.getMonth() + 1
    var date = t.getDate()
    var hour = t.getHours()
    var minute = t.getMinutes()
    var second = t.getSeconds()
    var s = {
      year,
      month: Appendzero(month),
      date: Appendzero(date),
      hour: Appendzero(hour),
      minute: Appendzero(minute),
      second: Appendzero(second),
    }
    return s
  },
  /**
   * 获取时分秒
   * @param now  需要获取的时间戳
   * return  返回一个对象，里面包含指定时间戳格式化的年月日时分秒
   */
  getTime (nowtime, endtime) {
    var lefttime = endtime - nowtime, //距离结束时间的毫秒数
      leftd = Math.floor(lefttime / (1000 * 60 * 60 * 24)), //计算天数
      lefth = Math.floor((lefttime / (1000 * 60 * 60)) % 24), //计算小时数
      leftm = Math.floor((lefttime / (1000 * 60)) % 60), //计算分钟数
      lefts = Math.floor((lefttime / 1000) % 60) //计算秒数
    return { day: leftd, hour: lefth, min: leftm, second: lefts }
  },
  /**
   * 前端复制功能
   * @param data  需要复制的文本
   */
  setClipboardData (data) {
    return new Promise((success, fail) => {
      const textarea = document.createElement('textarea')
      textarea.value = data
      textarea.readOnly = 'readOnly'
      document.body.appendChild(textarea)
      textarea.select()
      textarea.setSelectionRange(0, data.length)
      document.execCommand('copy')
      textarea.remove()
      success(data)
    })
  },
  /**
   * 判断是否是安卓
   */
  isAndroid () {
    var u = navigator.userAgent
    return u.indexOf('Android') > -1 || u.indexOf('Adr') > -1
  },
  /**
   * 判断是否是IOS
   */
  isiOS () {
    var u = navigator.userAgent
    return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
  },
  /**
   * 判断是否是mac
   */
  isMac () {
    var u = navigator.userAgent
    return /macintosh|mac os x/i.test(u);
  },
  // mac
  MAC () {
    var agent = navigator.userAgent.toLowerCase();
    var MAC = /macintosh|mac os x/i.test(navigator.userAgent) && !window.MSStream;
    return MAC;
  },
  getPlatform () {
    var platform = ''
    if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
      //ios
      if (this.isiOS()) {
        platform = 'ios'
      }
      //isAndroid
      if (this.isAndroid()) {
        platform = 'android'
      }
    }
    else {
      if (navigator.userAgent.indexOf("Win") >= 0 || navigator.userAgent.indexOf("Win") >= 0) {
        platform = 'windows'
      }
      if (this.isMac()) {
        platform = 'mac'
      }
    }
    return platform
  },
  /**
   * 個性化時間
   */
  beautify_time (timestamp) {
    var mistiming = Math.round(new Date() / 1000) - timestamp;
    var week = "星期" + "日一二三四五六".charAt(new Date(timestamp * 1000).getDay())
    var toolsTime = this.formatDate(timestamp * 1000)
    var postfix = mistiming > 0 ? '前' : '后'
    mistiming = Math.abs(mistiming)
    console.log('mistiming', mistiming)
    var arrr = ['年', '個月', '星期', '天', '小时', '分钟', '秒'];
    var arrn = [31536000, 2592000, 604800, 86400, 3600, 60, 1];
    var timeStae = ''
    for (var i = 0; i < 7; i++) {
      var inm = Math.floor(mistiming / arrn[i])
      console.log('inm', inm)
      if (inm != 0) {
        if (mistiming <= 59) {
          timeStae = inm + arrr[i] + postfix
          return timeStae
        } else if (mistiming >= 60 && mistiming <= 3599) {
          timeStae = inm + arrr[i] + postfix
          return timeStae
        } else if (mistiming >= 3600 && mistiming <= 3599 * 24) {
          timeStae = inm + arrr[i] + postfix
          return timeStae
        } else if (mistiming >= 86400 && mistiming <= 86399 * 2) {
          timeStae = '昨天'
          return timeStae
        } else if (mistiming >= 86400 * 2 && mistiming <= 604799) {
          timeStae = week
          return timeStae
        } else if (mistiming >= 604800) {
          timeStae = toolsTime.year + '/' + toolsTime.month + '/' + toolsTime.date
          return timeStae
        }
      }
    }
  },
  /**
   * 個性化時間
   */
  beautify_time2 (timestamp) {
    var mistiming = Math.round(new Date() / 1000) - timestamp;
    var postfix = mistiming > 0 ? '前' : '后'
    mistiming = Math.abs(mistiming)
    var arrr = ['年', '个月', '星期', '天', '小时', '分钟', '秒'];
    var arrn = [31536000, 2592000, 604800, 86400, 3600, 60, 1];

    for (var i = 0; i < 7; i++) {
      var inm = Math.floor(mistiming / arrn[i])
      if (inm != 0) {
        return inm + arrr[i] + postfix
      }
    }
  }
}
export default tools